# encoding=utf8
from flask import Flask, request, jsonify
from module.dimension_classifier.dimension_classifier import DimensionDetection

import module.condition_classifier.Classifier as condition_classifier
# from module.intention_classifier.intention_classifier import agg_module_interface
from module.intention_classifier.intention_classifier1 import IntentionClassfier
from utils.DataLoader import DataLoader
from utils.operation_separate import break_ques
import sys
import traceback
app = Flask(__name__)


@app.route('/getSQLs_error', methods=["POST"])
def getSQLs():
    # 这里面就是你想要返回给前端的值， 切记，这里只能返回字符串，如果是个json数据，你的通过json.dumps(你的json数据)
    front_data = request.get_json()
    status = front_data['status']
    data = front_data['data']

    if status == 300:
        res = []
        metaData_path = "./metaData/data_dict.json"
        question = data['question']
        dim_dict = data['dimensions']
        # 维度分类
        try:
            dim_detect = DimensionDetection(metaData_path)
            detect_result = dim_detect.detect(question)

            # 元数据查询，但不会在status==300这个分支触发
            if len(detect_result) == 1:
                (meta_output) = detect_result
                meta_output = dim_detect.meta_output_formatter(question, meta_output)
                ans = {"status": 200, "data": meta_output}
                return jsonify(ans)

            (dim_output, choices, like_dict, dim_pos) = detect_result
            dim_pos = dim_detect.add_dim_pos(dim_pos, dim_dict, question)

            dim_output = dim_detect.add_dim_to_output(dim_output, dim_dict)
            dim_output = dim_detect.output_formatter(question, dim_output)
            if len(like_dict) > 0:
                dim_output = dim_detect.like_formatter(dim_output, like_dict)
            dim_output = dim_detect.like_formatter(dim_output, dim_dict)
        except Exception as e:
            print(traceback.format_exc())
            error_data={"error_info": str(traceback.format_exc())}
            info={"status": 500, "data": error_data}
            return jsonify(info)
        # # 矛盾操作拆分
        # dict_list_after_break = break_ques(dim_output)
        # # 意图识别
        # intent_outputs = []
        # for dim_output_after_break in dict_list_after_break:
        #     intent_outputs.append(agg_module_interface(dim_output_after_break))
        try:
            intent_detect=IntentionClassfier(metaData_path)
            intent_outputs=intent_detect.predict(dim_output,dim_pos)
        except Exception as e:
            print(traceback.format_exc())
            error_data={"error_info": str(traceback.format_exc())}
            info={"status": 500, "data": error_data}
            return jsonify(info)
        # 条件分类
        try:
            for intent_output in intent_outputs:
                cond_detect = condition_classifier.Classifier(metaData_path)
                final_output = cond_detect.classification(intent_output['question'], intent_output['sel'],
                                                        intent_output['agg'], intent_output['limit'],
                                                        intent_output['measure'], dim_output['like'],dim_dict)
                sqls = formatter(final_output)
                res.extend(sqls)
            print(res)
            ans = {"status": 200, "data": res}
        except Exception as e:
            print(traceback.format_exc())
            error_data={"error_info": str(traceback.format_exc())}
            info={"status": 500, "data": error_data}
            return jsonify(info)
        
        return jsonify(ans)
    elif status == 200:
        res = []
        metaData_path = "./metaData/data_dict.json"
        question = data['question']
        # 维度分类
        try:
            dim_detect = DimensionDetection(metaData_path)
            detect_result = dim_detect.detect(question)

            # 元数据查询
            if len(detect_result) == 1:
                (meta_output) = detect_result
                meta_output = dim_detect.meta_output_formatter(question, meta_output)
                ans = {"status": 200, "data": meta_output}
                return jsonify(ans)

            (dim_output, choices, like_dict, dim_pos) = detect_result
            dim_output = dim_detect.output_formatter(question, dim_output)
            if len(like_dict) > 0:
                dim_output = dim_detect.like_formatter(dim_output, like_dict)
        except Exception as e:
            print(traceback.format_exc())
            error_data={"error_info": str(traceback.format_exc())}
            info={"status": 500, "data": error_data}
            return jsonify(info)
        if len(choices) > 0:
            try:
                choices = dim_detect.choice_formatter(choices)
                res += choices
                print(res)
                ans = {"status": 300, "data": res}
            except Exception as e:
                print(traceback.format_exc())
                error_data={"error_info": str(traceback.format_exc())}
                info={"status": 500, "data": error_data}
                return jsonify(info)
        else:
            # # 矛盾操作拆分
            # dict_list_after_break = break_ques(dim_output)
            # # 意图识别
            # intent_outputs = []
            # for dim_output_after_break in dict_list_after_break:
            #     intent_outputs.append(agg_module_interface(dim_output_after_break))
            try:
                intent_detect=IntentionClassfier(metaData_path)
                intent_outputs=intent_detect.predict(dim_output,dim_pos)
            except Exception as e:
                print(traceback.format_exc())
                error_data={"error_info": str(traceback.format_exc())}
                info={"status": 500, "data": error_data}
                return jsonify(info)
            # 条件分类
            try:
                for intent_output in intent_outputs:
                    cond_detect = condition_classifier.Classifier(metaData_path)
                    final_output = cond_detect.classification(intent_output['question'], intent_output['sel'],
                                                            intent_output['agg'], intent_output['limit'],
                                                            intent_output['measure'], dim_output['like'], None)
                    sqls = formatter(final_output)
                    res.extend(sqls)
                print(res)
                ans = {"status": 200, "data": res}
            except Exception as e:
                print(traceback.format_exc())
                error_data={"error_info": str(traceback.format_exc())}
                info={"status": 500, "data": error_data}
                return jsonify(info)
        return jsonify(ans)
    else:
        raise ValueError('Status must be 200 or 300')


def formatter(sqls):
    """
    将后端输出格式化为前端需要的形式
    :param sqls: 意图识别模块输出的结果[{},{}]
    :return:
    """
    res = []
    for sql in sqls:
        temp_res = []
        for key, val in sql.items():
            temp_res.append({"key": key, "content": str(val)})
        res.append(temp_res)

    return res


if __name__ == '__main__':
    # 这里host是你的后端地址，这里写0.0.0.0， 表示的是这个接口在任何服务器上都可以被访问的到，只需要前端访问该服务器地址就可以的，
    # 当然你也可以写死，如222.222.222.222， 那么前端只能访问222.222.222.222, port是该接口的端口号,
    # debug = True ,表示的是，调试模式，每次修改代码后不用重新启动服务
    app.run(host='0.0.0.0', port=80, debug=True)
    # app.run(host='0.0.0.0', port=5001, debug=True)
